package cn.faifai.tagapi.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.util.Set;

@Entity
//@Data
/*
    审计功能，对数据的创建、最后更新时间以及创建、最后操作人进行记录
 */
@EntityListeners(AuditingEntityListener.class)//开启审计监听
@Table(name = "file")
//@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
@Getter
@Setter
@EqualsAndHashCode(exclude = {"tags"})
public class IFile extends BaseEntity{
    @Id
    @Column(name = "id")
    @GeneratedValue(generator = "snowflake")
    @GenericGenerator(name = "snowflake", strategy = "cn.faifai.framework.config.jpa.SnowFlakeIdGenerator")
    private Long id;

    /**
     * 操作系统文件id
     */
    @Column(name = "os_file_id")
    private String osFileId;

    @Column(name = "file_name")
    private String fileName;

    /**
     * 注册磁盘
     */
    @Column(name = "disk")
    private String disk;

    /**
     * 地址（相对磁盘）
     */
    @Column(name = "path")
    private String path;

    /**
     * 文件后缀
     */
    @Column(name = "suffix")
    private String suffix;

    /**
     * 文件校验
     */
    @Column(name = "SHA256_str")
    private String SHA256Str;

    /**
     * 硬链接状态：0-不存在 1-存在
     */
    @Column(name = "hard_link_status")
    private Integer hardLinkStatus = 0;

    /**
     * 预删除状态（标记回收站）：0-未收入回收站 1-已收入回收站 2-怀疑已还原 3-怀疑已永久删除
     */
    @Column(name = "pre_delete_status")
    private Integer preDeleteStatus = 0;

    /**
     * 操作系统
     */
    @Column(name = "os")
    private String os;

    /**
     * 回收站文件路径
     */
    @Column(name = "recycle_bin_file_path")
    private String recycleBinFilePath;




    /**
     * file与tag是多对多的关系，据了解JPA中使用@ManyToMany来注解多对多的关系，由一个关联表来维护。
     * 两个实体都需要加一个Set来保存多对多关系，多对多关系的绑定只能由关系维护端来完成，
     * 可以随意指定一方为关系维护端，暂时设关系维护实体为b，另一个为a。解除关系有限制，只能由b来调用set集合的remove方法解除
     * a不能解除关系，也不能直接删除，只能先由b解除关系，才能删除a，而b不同，可以直接删除b，看解释说明
     * 应该是系统用b解除关系，再删除b，待确认。
     * 在多对多关系中，一般不设置级联删除，这会导致删除B时也会同时删除与之相关联的A实体，所以通常不建议用
     * @ManyToMany(cascade = CascadeType.ALL)
     */
    // 使用 @ManyToMany 注解定义多对多关系
    // 并使用 @JoinTable 注解来显式定义中间表（可选，但有助于清晰表达）
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch = FetchType.LAZY)
    @JoinTable(
            // 中间表名
            name = "file_tag",
            joinColumns = @JoinColumn(name = "file_id"),//当前实体（file）在中间表中的外键列
            inverseJoinColumns = @JoinColumn(name = "tag_id")//关系的另一方（tag）在中间表中的外键列
    )
    @JsonIgnore
    private Set<Tag> tags;

    public IFile(){}
    public IFile(String path,String SHA256Str){
        this.path=path;
        this.SHA256Str=SHA256Str;
    }
    public IFile(String disk,String path,String SHA256Str){
        this.disk=disk;
        this.path=path;
        this.SHA256Str=SHA256Str;
    }
    public IFile(String disk,String path,String SHA256Str,String suffix){
        this.disk=disk;
        this.path=path;
        this.SHA256Str=SHA256Str;
        this.suffix=suffix;
    }
    public IFile(String disk,String path,String SHA256Str,String suffix,Integer hardLinkStatus){
        this.disk=disk;
        this.path=path;
        this.SHA256Str=SHA256Str;
        this.suffix=suffix;
        this.hardLinkStatus=hardLinkStatus;
    }
    public IFile(String fileName,String disk,String path,String SHA256Str,String suffix,Integer hardLinkStatus){
        this.fileName=fileName;
        this.disk=disk;
        this.path=path;
        this.SHA256Str=SHA256Str;
        this.suffix=suffix;
        this.hardLinkStatus=hardLinkStatus;
    }
}
